
local kong = kong
local ngx = ngx
local string = string
local time = ngx.time
local localtime = ngx.localtime
local json = require "cjson"
local kong_shared = ngx.shared.kong

local singletons = require "kong.singletons"
local constants = require "kong.constants"
local uuid = require "kong.tools.utils".uuid
local plugin_name = ({...})[1]:match("^kong%.plugins%.([^%.]+)")
-- local http_sender = require "kong.plugins.plugin-manage.sender.http_sender"
local http_sender = require("kong.plugins." .. plugin_name .. ".sender.http_sender")
-- local tools = require "kong.plugins.plugin-manage.tools"
local tools = require("kong.plugins." .. plugin_name .. ".tools")

local lfs = require("lfs")

local HTTP_OK           = 200
local HTTP_BAD_REQUEST  = 400
local HTTP_SERVER_ERROR = 500

-- 更新配置文件
local function update_conf(conf_detail)
  local localtime_str = localtime()
  localtime_str = localtime_str:gsub("[-: ]", "")

  local conf_path = tools.get_default_conf_path()
  local conf_name = tools.get_default_conf_name()
  local tmp_conf_name = tools.get_default_tmp_conf_name()

  local kong_back_filename = string.format(tools.get_default_backup_conf_format(), localtime_str)

  -- 进入配置目录
  local ok, err = os.execute("cd " .. conf_path)
  if not ok then
    local msg = "进入配置文件目录失败：" .. err
    return HTTP_SERVER_ERROR, msg
  end

  -- 写入临时文件
  local tmp_file_path = conf_path .. tmp_conf_name
  local tmp_file, tmp_file_err = io.open(tmp_file_path, "w+")
  if not tmp_file then
    local msg = "创建临时文件失败：" + tmp_file_err
    return HTTP_SERVER_ERROR, tmp_file_err
  end
  ok, err = tmp_file:write(conf_detail)
  if not ok then
    local msg = "写入临时文件失败：" .. err
    return HTTP_SERVER_ERROR, msg
  end
  tmp_file:close()

  -- 校验临时文件
  local res_msg = ""
  local res = io.popen("/usr/local/bin/kong check " .. tmp_file_path.. " --vv")
  if res then
    res_msg = res_msg .. "kong 配置校验结果：\n"

    for row in res:lines() do
      res_msg = res_msg .. row .. "\n"
    end
    res:close()
  else
    res_msg = res_msg .. "kong 配置校验失败或配置校验结果为空。\n"
    local remove_res = os.remove(tmp_conf_name)
    if not remove_res then
      res_msg = res_msg .. "删除临时文件失败。"
    else
      res_msg = res_msg .. "已删除临时文件。"
    end
    return HTTP_BAD_REQUEST, res_msg
  end

  -- 读取原配置文件内容
  local origin_file, origin_file_err = io.open(conf_path .. conf_name, "r")
  if not origin_file then
    local msg = "读取原配置文件失败：" .. origin_file_err
    return HTTP_SERVER_ERROR, msg
  end
  local origin_data = origin_file:read("*a")
  origin_file:close()

  -- 备份原配置文件
  local back_file, back_file_err = io.open(conf_path .. kong_back_filename, "w+")
  if not back_file then
    local msg = "创建备份文件失败：" .. back_file_err
    return HTTP_SERVER_ERROR, msg
  end
  ok, err = back_file:write(origin_data)
  if not ok then
    local msg = "备份原配置文件失败：" .. err
    return HTTP_SERVER_ERROR, msg
  end
  back_file:close()

  origin_file, origin_file_err = io.open(conf_path .. conf_name, "w+")
  if not origin_file then
    local msg = "读取原配置文件失败：" .. origin_file_err
    return HTTP_SERVER_ERROR, msg
  end
  ok, err = origin_file:write(conf_detail)
  if not ok then
    local msg = "配置文件写入失败：" .. err
    return HTTP_SERVER_ERROR, msg
  end
  origin_file:close()
  return HTTP_OK, "配置推送成功"
end

-- 字符串分割函数
function split(s, delim)
    if type(delim) ~= "string" or string.len(delim) <= 0 then
        return
    end

    local start = 1
    local t = {}
    while true do
        local pos = string.find (s, delim, start, true) -- plain find
        if not pos then
            break
        end

        table.insert (t, string.sub (s, start, pos - 1))
        start = pos + string.len (delim)
    end
    table.insert (t, string.sub (s, start))

    return t
end

-- 格式化时间
function datetime_format(file)
    local back_time = split(file, "_")
    local datetime = back_time[2]

    local year = string.sub(datetime, 1, 4)
    local month = string.sub(datetime, 5, 6)
    local day = string.sub(datetime, 7, 8)
    local hour = string.sub(datetime, 9, 10)
    local minute = string.sub(datetime, 11, 12)
    local second = string.sub(datetime, 13, 14)
    date = {year, month, day}
    time_my = {hour, minute, second}

    return table.concat(date, '-') .. ' ' .. table.concat(time_my, ':')

end
-- 静态配置版本查询  配置文件列表
local function list_versions()

    local conf_path = tools.get_default_conf_path()
    local conf_name = tools.get_default_conf_name()

    local conf_list = {}

    for file in lfs.dir(conf_path) do
        local tmp_result = {}
        if string.match(file, "conf") ~= nil then
            if (tostring(file) == conf_name) then
                tmp_result["back_uptime"] = "current_version"
                conf_list[conf_name] = tmp_result
            end
            if string.match(file, "_back") ~= nil then
                tmp_result["back_uptime"] = datetime_format(file)
                conf_list[file] = tmp_result
            end
        end
    end

    return HTTP_OK, conf_list
end


-- 读取配置文件内容
local function version_detail(conf_version)
  local conf_path = tools.get_default_conf_path()
  local conf_name = conf_version

  local file, err = io.open(conf_path .. conf_name, "r")
  if not file then
    local msg = "读取配置文件失败: " .. err
    return HTTP_SERVER_ERROR, msg
  end

  local data = file:read("*a")
  local result = {}
  result["file_detail"] = data
  return HTTP_OK, result
end

-- 删除配置文件
local function delete_conf(conf_version)
  local conf_path = tools.get_default_conf_path()
  local default_conf_name = tools.get_default_conf_name()
  local res_msg = ""

  if conf_version == default_conf_name then
    res_msg = "删除失败，无法删除此配置文件。"
    return HTTP_BAD_REQUEST, res_msg
  end

  -- 判断文件是否存在
  local file, err = io.open(conf_path .. conf_version, "r")
  if not file then
    res_msg = "删除失败，版本不存在。"
    return HTTP_BAD_REQUEST, res_msg
  end

  -- 删除文件
  local remove_res = os.remove(conf_path .. conf_version)
  if remove_res then
    res_msg = "删除成功。"
  else
    res_msg = "删除失败，版本不存在。"
    return HTTP_BAD_REQUEST, res_msg
  end
  return HTTP_OK, res_msg
end

return {
  DEFAULT_PLUGINS_PATH = tools.DEFAULT_PLUGINS_PATH,
  DEFAULT_CONF_PATH = tools.DEFAULT_CONF_PATH,
  DEFAULT_CONF_NAME = tools.DEFAULT_CONF_NAME,

  get_pod_hostname = tools.get_pod_hostname,
  get_pod_ip = tools.get_pod_ip,
  get_default_plugins_path = tools.get_default_plugins_path,
  get_default_conf_path = tools.get_default_conf_path,
  get_default_conf_name = tools.get_default_conf_name,

  HTTP_OK = HTTP_OK,
  HTTP_BAD_REQUEST = HTTP_BAD_REQUEST,
  HTTP_SERVER_ERROR = HTTP_SERVER_ERROR,

  update_conf = update_conf,
  version_detail = version_detail,
  delete_conf = delete_conf,
  list_versions = list_versions
}
